package com.wsoft.oss.controller;

import com.wsoft.constant.CommonConstant;
import com.wsoft.oss.entity.OssFileEntity;
import com.wsoft.oss.manager.OssFileManager;
import com.wsoft.oss.query.FileInfoQuery;
import com.wsoft.oss.service.IOssFileService;
import com.wsoft.oss.service.IOssService;
import com.wsoft.response.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

/**
 *  前端控制器
 * @author z001
 * @since 2024年09月26日 15:17:53
 */
@RestController
@Tag(name = "oss附件")
@RequestMapping("/pub/file")
public class PubFileController {

    @Resource
    private IOssFileService ossFileService;
    @Resource
    @Lazy
    private IOssService ossService;
    @Resource
    private OssFileManager ossFileManager;

    @Operation(summary = "下载文件", description = "下载文件")
    @GetMapping("/download")
    public ResponseEntity download(@RequestParam("id") Long id,
                              @RequestParam(value = "picType",required = false) Integer picType,
                              @RequestParam(value = "sessionId",required = false) String sessionId,
                                   HttpServletRequest request) throws Exception{

        Map<String, Object> map = ossFileService.get(id,picType,sessionId);

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(map.get("fileName").toString(), "UTF-8"));
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
        headers.add(HttpHeaders.PRAGMA, "no-cache");
        headers.add(HttpHeaders.EXPIRES, "0");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,HttpHeaders.CONTENT_DISPOSITION);

        return ResponseEntity.ok()
                .headers(headers)
                .body(map.get("stream"));
    }


    @Operation(summary = "分片下载文件", description = "分片下载文件")
    @GetMapping("/downloadPart")
    public ResponseEntity downloadPart(@RequestParam("id") Long id,
                                       @RequestParam(value = "picType",required = false) Integer picType,
                                       HttpServletRequest request, HttpServletResponse response) throws Exception{
        String sessionId = request.getHeader(CommonConstant.SESSION_ID);
        String range = request.getHeader(CommonConstant.RANGE);
        OssFileEntity fileEntity = ossFileManager.getById(id);

        byte[] bytes = ossFileService.downloadPart(fileEntity,picType,sessionId,range,response);
        InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,HttpHeaders.CONTENT_DISPOSITION);
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileEntity.getName(), "UTF-8"));
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
        headers.add(HttpHeaders.PRAGMA, "no-cache");
        headers.add(HttpHeaders.EXPIRES, "0");
        return ResponseEntity.ok()
                .headers(headers)
                .body(resource);
    }

    // ####################################################################

    @Operation(summary = "预览", description = "预览")
    @GetMapping("/preview")
    public ResponseResult preview(@RequestParam(value = "id") Long fileId,
                                  @RequestParam(value = "sessionId",required = false) String sessionId) throws Exception {
        return ResponseResult.success(ossService.preview(fileId,sessionId));
    }

    @Operation(summary = "在线预览", description = "在线预览")
    @GetMapping("/previewOnline")
    public ResponseEntity previewOnline(@RequestParam("id") Long id,
                                     @RequestParam(value = "picType",required = false) Integer picType,
                                     @RequestParam(value = "sessionId",required = false) String sessionId) throws Exception{

        Map<String, Object> map = ossFileService.get(id,picType,sessionId);
        String fileName = map.get("fileName").toString();

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
        headers.add(HttpHeaders.PRAGMA, "no-cache");
        headers.add(HttpHeaders.EXPIRES, "0");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,HttpHeaders.CONTENT_DISPOSITION);

        MediaType mediaType = MediaTypeFactory.getMediaType(fileName).orElse(MediaType.APPLICATION_OCTET_STREAM);


        return ResponseEntity.ok()
                .headers(headers).contentType(mediaType)
                .body(map.get("stream"));
    }

    @Operation(summary = "查询文件详情", description = "查询文件详情")
    @PostMapping("/getFileInfo")
    public ResponseResult getFileInfo(@RequestBody FileInfoQuery query){
        return ResponseResult.success(ossFileService.getFileInfo(query));
    }


}
